package com.codefish.framework.spring.beans.factory.support;

import com.codefish.framework.spring.beans.factory.config.IConfigurableBeanFactory;
import com.codefish.framework.spring.core.utils.ObjectUtils;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

/**
 * BeanDefinition，定义一个bean的所有信息
 *
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/09/23 下午 04:08
 */
@Getter
@Setter
public class BeanDefinition {
    private static final String SCOPE_SINGLETON = IConfigurableBeanFactory.SCOPE_SINGLETON;
    private static final String SCOPE_PROTOTYPE = IConfigurableBeanFactory.SCOPE_PROTOTYPE;
    private static final String SCOPE_DEFAULT = "";

    /**
     * bean所属的class对象
     */
    private volatile Class<?> beanClass;
    /**
     * bean对应的属性名和value
     */
    private List<PropertyValue> propertyValues;
    /**
     * bean的scope标识
     */
    private String scope = SCOPE_DEFAULT;
    /**
     * bean自定义初始化方法
     */
    private String initMethod;
    /**
     * bean自定义销毁方法
     */
    private String destroyMethod;
    /**
     * 如果这个bean为factoryBean，则factoryBeanName不为null
     */
    private String factoryBeanName;
    /**
     * 是否懒加载
     */
    private boolean lazyInit = false;


    public BeanDefinition(Class<?> beanClass) {
        this.beanClass = beanClass;
        this.propertyValues = new ArrayList<>();
    }

    public void addPropertyValue(PropertyValue propertyValue) {
        this.propertyValues.add(propertyValue);
    }

    public boolean isSingleton() {
        return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
    }

    public boolean isPrototype() {
        return SCOPE_PROTOTYPE.equals(scope);
    }

    @Override
    public int hashCode() {
        int hashCode = ObjectUtils.nullSafeHashCode(this.beanClass);
        hashCode += 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) {
       if(obj==this){
           return true;
       }
       if(!(obj instanceof BeanDefinition)){
           return false;
       }
       BeanDefinition that = (BeanDefinition) obj;
       return ObjectUtils.nullSafeEquals(this.beanClass,that.beanClass)
               && ObjectUtils.nullSafeEquals(this.propertyValues,that.propertyValues);
    }
}
